﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RAE.Logica.Info;
using RAE.Persistencia;
using RAE.Logica.Torneos;

namespace RAE.Logica.Controladores
{
    public enum Usuario {
        VISITA,
        ENCARGADO_ELO,
        ADMINISTRADOR 
    }

    public static class Aplicacion
    {
        public static int puntaje_elo_min            { get; set; }
        public static List<Ajedrecista> ajedrecistas { get; set; }
        public static List<Categoria> categorias     { get; set; }
        public static Dictionary<int,Titulo> titulos { get; set; }
        public static Dictionary<int,Pais> paises    { get; set; }
        public static Usuario usuario_actual         { get; set; }
        public static List<Periodo> periodos         { get; set; } 

        public static void inicializar()
        {
            Cargador.inicializar();

            puntaje_elo_min = Cargador.obtenerPuntajeEloMin();

            categorias   = Cargador.obtenerCategorias ();
            titulos      = Cargador.obtenerTitulos    ();
            paises       = Cargador.obtenerPaises     ();
            periodos     = Cargador.obtenerPeriodos   ();
            
            initAjedrecistas();
        }

        public static void initAjedrecistas()
        {
            ajedrecistas = Cargador.obtenerAjerecistas();

            foreach (Ajedrecista a in ajedrecistas)
            {
                a.titulos = Cargador.obtenerTitulosPorAjedrecista(a);
                a.gettitulos();
            }

            categorizarAjedrecistas();
        }

        public static void categorizarAjedrecistas()
        {
            foreach (Ajedrecista a in ajedrecistas)
            {
                foreach (Categoria c in categorias)
                {
                    if (a.enCategoria(c))
                    {
                        a.categoria = c;
                        break;
                    }
                }
            }
        }

        public static bool autenticarUsuario(Usuario user, string contraseña)
        {
            switch (user)
            {
                case Usuario.VISITA:
                    return true;
                case Usuario.ENCARGADO_ELO:
                    return Cargador.autenticarEncargadoElo(contraseña);
                case Usuario.ADMINISTRADOR:
                    return Cargador.autenticarAdministrador(contraseña);
                default:
                    return false;
            }
        }

        public static void registrarAjedrecista(Ajedrecista a)
        {
            a.puntaje_elo = puntaje_elo_min;
            Cargador.registrarAjedrecista(a);
            initAjedrecistas();
        }

        public static void actualizarAjedrecista(Ajedrecista a)
        {
            Cargador.actualizarAjedrecista(a);
            initAjedrecistas();
        }

        public static void cambiarConfiguracion(int nuevo_elo)
        {
            Cargador.modificarEloMinimo(nuevo_elo);
            puntaje_elo_min = nuevo_elo;
        }

        public static void actualizarCategorias(List<Categoria> anteriores)
        {
            List<Categoria> addCategories = new List<Categoria>();
            List<Categoria> modCategories = new List<Categoria>();
            List<Categoria> delCategories = new List<Categoria>();

            foreach (Categoria categoryA in categorias)
            {
                if (categoryA.nombre != "")
                {
                    Categoria categoryB;
                    int position = indice(anteriores, categoryA);

                    if (position >= 0)
                    {
                        categoryB = anteriores[position];

                        if ((categoryA.puntaje_elo_min != categoryB.puntaje_elo_min) ||
                            (categoryA.coeficiente != categoryB.coeficiente))
                        {
                            categoryB.puntaje_elo_min = categoryA.puntaje_elo_min;
                            categoryB.coeficiente = categoryA.coeficiente;
                            modCategories.Add(categoryA);
                        }
                    }
                    else
                    {
                        addCategories.Add(categoryA);
                        anteriores.Add(categoryA);
                    }
                }
                //else MessageBox.Show("Todas las líneas de categoría sin nombre\nserán ignoradas.");
            }

            bool[] remover = new bool[anteriores.Count];
            for (int i = 0; i < anteriores.Count; i++)
            //foreach (Categoria categoryA in anteriores)
            {
                Categoria categoryA = anteriores[i];
                if (indice(categorias, categoryA) < 0)
                {
                    delCategories.Add(categoryA);
                    remover[i] = true;
                }
                else remover[i] = false;
            }

            for (int i = remover.Length - 1; i >= 0; i--)
                if (remover[i])
                    anteriores.RemoveAt(i);

            foreach (Categoria category in addCategories)
                Cargador.agregarCategoria(category);
            foreach (Categoria category in modCategories)
                Cargador.modificarCategoria(category);
            foreach (Categoria category in delCategories)
                Cargador.borrarCategoria(category);
        }

        private static int indice(List<Categoria> categorias, Categoria categoria)
        {
            Categoria actual;
            for (int i = 0; i < categorias.Count; i++)
            {
                actual = categorias[i];
                if (categoria.nombre == actual.nombre)
                    return i;
            }
            return -1;
        }

        public static void cargarPeriodos() 
        {
            periodos = Cargador.obtenerPeriodos();
        }

        public static void procesarNuevoTorneo(Torneo t)
        {
            CalculadorElo.actualizarPuntajesElo(t);
            Cargador.registrarTorneo(t);
        }
    }
}
